package examples.gp;


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

import org.jgap.gp.CommandGene;
import org.jgap.gp.IGPProgram;
import org.jgap.gp.impl.GPConfiguration;
import org.jgap.gp.terminal.Variable;


public class Main {

	private static int NUM_STOCKS_CHOSEN;
	private static Double THRESH;

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		/*for(int i=6;i<205;i++)
			System.out.println("Variable vx"+i+"=holder.getVx"+i+"();");
		if(true)
			return;
		*/
		if(args.length<5)
			return;

		//initializing variables

		boolean isTrain=false;
		if(args[0].intern()=="-t")
			isTrain=true;
		int numDays=Integer.parseInt(args[1]);
		String modelFile=args[4], filenames=args[3], datafolder=args[2];

		BufferedReader br = null;
		BufferedReader brr = null;

		//if(isTrain)
		{
			// GPConfiguration conf = getGPConfiguration();
		//	StockProblem gp = new StockProblem();
			String str2=null;
			try 
			{

				brr=new BufferedReader(new FileReader(filenames));

				ArrayList<Stock> stocks=new ArrayList<Stock>();

				ArrayList<Double> prices;
				String str;
				// as long as the file has more lines to read
				while ((str = brr.readLine()) != null)
				{
					br=new BufferedReader(new FileReader(datafolder+"/"+str));
					prices=new ArrayList<Double>();
					String name="";
					while((str2=br.readLine()) != null)
					{
						String [] splitted=str2.split(",");
						name=splitted[0];
						prices.add(Double.parseDouble(splitted[5]));
					}
					stocks.add(new Stock(name,prices));
					br.close();
				}


				
				brr.close();
				
				//printing the date of beginning of the algorithm
				System.out.println(new java.util.Date());


				if(numDays>50)
					numDays=50;
				
				if(isTrain){
				//running random algorithm for monkey problem
				StockProblem.run_alg(stocks,numDays,modelFile);


				//printing date of finish
				System.out.println(new java.util.Date());
				}
				else{

					String destFile=args[5];
					FileInputStream fw;
					
					fw = new FileInputStream(modelFile);
					
				    ObjectInputStream os=new ObjectInputStream(fw);
				    IGPProgramHolder holder=(IGPProgramHolder) os.readObject();
				    IGPProgram gp=holder.getGPProgram();
				    Variable vx1=holder.getVx1();
				    Variable vx2=holder.getVx2();
				    Variable vx3=holder.getVx3();
				    Variable vx4=holder.getVx4();
				 
				    /*Variable vx5=holder.getVx5();
				    Variable vx6=holder.getVx6();
				    Variable vx7=holder.getVx7();
				    Variable vx8=holder.getVx8();
				    Variable vx9=holder.getVx9();
				    Variable vx10=holder.getVx10();
				    Variable vx11=holder.getVx11();
				    Variable vx12=holder.getVx12();
				    Variable vx13=holder.getVx13();
				    Variable vx14=holder.getVx14();
				    Variable vx15=holder.getVx15();
				    Variable vx16=holder.getVx16();
				    Variable vx17=holder.getVx17();
				    Variable vx18=holder.getVx18();
				    Variable vx19=holder.getVx19();
				    Variable vx20=holder.getVx20();
				    Variable vx21=holder.getVx21();
				    Variable vx22=holder.getVx22();
				    Variable vx23=holder.getVx23();
				    Variable vx24=holder.getVx24();
				    Variable vx25=holder.getVx25();
				    Variable vx26=holder.getVx26();
				    Variable vx27=holder.getVx27();
				    Variable vx28=holder.getVx28();
				    Variable vx29=holder.getVx29();
				    Variable vx30=holder.getVx30();
				    Variable vx31=holder.getVx31();
				    Variable vx32=holder.getVx32();
				    Variable vx33=holder.getVx33();
				    Variable vx34=holder.getVx34();
				    Variable vx35=holder.getVx35();
				    Variable vx36=holder.getVx36();
				    Variable vx37=holder.getVx37();
				    Variable vx38=holder.getVx38();
				    Variable vx39=holder.getVx39();
				    Variable vx40=holder.getVx40();
				    Variable vx41=holder.getVx41();
				    Variable vx42=holder.getVx42();
				    Variable vx43=holder.getVx43();
				    Variable vx44=holder.getVx44();
				    Variable vx45=holder.getVx45();
				    Variable vx46=holder.getVx46();
				    Variable vx47=holder.getVx47();
				    Variable vx48=holder.getVx48();
				    Variable vx49=holder.getVx49();
				    Variable vx50=holder.getVx50();
				    Variable vx51=holder.getVx51();
				    Variable vx52=holder.getVx52();
				    Variable vx53=holder.getVx53();
				    Variable vx54=holder.getVx54();
				    Variable vx55=holder.getVx55();
				    Variable vx56=holder.getVx56();
				    Variable vx57=holder.getVx57();
				    Variable vx58=holder.getVx58();
				    Variable vx59=holder.getVx59();
				    Variable vx60=holder.getVx60();
				    Variable vx61=holder.getVx61();
				    Variable vx62=holder.getVx62();
				    Variable vx63=holder.getVx63();
				    Variable vx64=holder.getVx64();
				    Variable vx65=holder.getVx65();
				    Variable vx66=holder.getVx66();
				    Variable vx67=holder.getVx67();
				    Variable vx68=holder.getVx68();
				    Variable vx69=holder.getVx69();
				    Variable vx70=holder.getVx70();
				    Variable vx71=holder.getVx71();
				    Variable vx72=holder.getVx72();
				    Variable vx73=holder.getVx73();
				    Variable vx74=holder.getVx74();
				    Variable vx75=holder.getVx75();
				    Variable vx76=holder.getVx76();
				    Variable vx77=holder.getVx77();
				    Variable vx78=holder.getVx78();
				    Variable vx79=holder.getVx79();
				    Variable vx80=holder.getVx80();
				    Variable vx81=holder.getVx81();
				    Variable vx82=holder.getVx82();
				    Variable vx83=holder.getVx83();
				    Variable vx84=holder.getVx84();
				    Variable vx85=holder.getVx85();
				    Variable vx86=holder.getVx86();
				    Variable vx87=holder.getVx87();
				    Variable vx88=holder.getVx88();
				    Variable vx89=holder.getVx89();
				    Variable vx90=holder.getVx90();
				    Variable vx91=holder.getVx91();
				    Variable vx92=holder.getVx92();
				    Variable vx93=holder.getVx93();
				    Variable vx94=holder.getVx94();
				    Variable vx95=holder.getVx95();
				    Variable vx96=holder.getVx96();
				    Variable vx97=holder.getVx97();
				    Variable vx98=holder.getVx98();
				    Variable vx99=holder.getVx99();
				    Variable vx100=holder.getVx100();
				    Variable vx101=holder.getVx101();
				    Variable vx102=holder.getVx102();
				    Variable vx103=holder.getVx103();
				    Variable vx104=holder.getVx104();
				    Variable vx105=holder.getVx105();
				    Variable vx106=holder.getVx106();
				    Variable vx107=holder.getVx107();
				    Variable vx108=holder.getVx108();
				    Variable vx109=holder.getVx109();
				    Variable vx110=holder.getVx110();
				    Variable vx111=holder.getVx111();
				    Variable vx112=holder.getVx112();
				    Variable vx113=holder.getVx113();
				    Variable vx114=holder.getVx114();
				    Variable vx115=holder.getVx115();
				    Variable vx116=holder.getVx116();
				    Variable vx117=holder.getVx117();
				    Variable vx118=holder.getVx118();
				    Variable vx119=holder.getVx119();
				    Variable vx120=holder.getVx120();
				    Variable vx121=holder.getVx121();
				    Variable vx122=holder.getVx122();
				    Variable vx123=holder.getVx123();
				    Variable vx124=holder.getVx124();
				    Variable vx125=holder.getVx125();
				    Variable vx126=holder.getVx126();
				    Variable vx127=holder.getVx127();
				    Variable vx128=holder.getVx128();
				    Variable vx129=holder.getVx129();
				    Variable vx130=holder.getVx130();
				    Variable vx131=holder.getVx131();
				    Variable vx132=holder.getVx132();
				    Variable vx133=holder.getVx133();
				    Variable vx134=holder.getVx134();
				    Variable vx135=holder.getVx135();
				    Variable vx136=holder.getVx136();
				    Variable vx137=holder.getVx137();
				    Variable vx138=holder.getVx138();
				    Variable vx139=holder.getVx139();
				    Variable vx140=holder.getVx140();
				    Variable vx141=holder.getVx141();
				    Variable vx142=holder.getVx142();
				    Variable vx143=holder.getVx143();
				    Variable vx144=holder.getVx144();
				    Variable vx145=holder.getVx145();
				    Variable vx146=holder.getVx146();
				    Variable vx147=holder.getVx147();
				    Variable vx148=holder.getVx148();
				    Variable vx149=holder.getVx149();
				    Variable vx150=holder.getVx150();
				    Variable vx151=holder.getVx151();
				    Variable vx152=holder.getVx152();
				   Variable vx153=holder.getVx153();
				   
				    Variable vx154=holder.getVx154();
				    Variable vx155=holder.getVx155();
				    Variable vx156=holder.getVx156();
				    Variable vx157=holder.getVx157();
				    Variable vx158=holder.getVx158();
				    Variable vx159=holder.getVx159();
				    Variable vx160=holder.getVx160();
				    Variable vx161=holder.getVx161();
				    Variable vx162=holder.getVx162();
				    Variable vx163=holder.getVx163();
				    Variable vx164=holder.getVx164();
				    Variable vx165=holder.getVx165();
				    Variable vx166=holder.getVx166();
				    Variable vx167=holder.getVx167();
				    Variable vx168=holder.getVx168();
				    Variable vx169=holder.getVx169();
				    Variable vx170=holder.getVx170();
				    Variable vx171=holder.getVx171();
				    Variable vx172=holder.getVx172();
				    Variable vx173=holder.getVx173();
				    Variable vx174=holder.getVx174();
				    Variable vx175=holder.getVx175();
				    Variable vx176=holder.getVx176();
				    Variable vx177=holder.getVx177();
				    Variable vx178=holder.getVx178();
				    Variable vx179=holder.getVx179();
				    Variable vx180=holder.getVx180();
				    Variable vx181=holder.getVx181();
				    Variable vx182=holder.getVx182();
				    Variable vx183=holder.getVx183();
				    Variable vx184=holder.getVx184();
				    Variable vx185=holder.getVx185();
				    Variable vx186=holder.getVx186();
				    Variable vx187=holder.getVx187();
				    Variable vx188=holder.getVx188();
				    Variable vx189=holder.getVx189();
				    Variable vx190=holder.getVx190();
				    Variable vx191=holder.getVx191();
				    Variable vx192=holder.getVx192();
				    Variable vx193=holder.getVx193();
				   
				    Variable vx194=holder.getVx194();
				    Variable vx195=holder.getVx195();
				    Variable vx196=holder.getVx196();
				    Variable vx197=holder.getVx197();
				    Variable vx198=holder.getVx198();
				    Variable vx199=holder.getVx199();*/
				    Variable vx200=holder.getVx200();
				    Variable vx201=holder.getVx201();
				    Variable vx202=holder.getVx202();
				    Variable vx203=holder.getVx203();
				    Variable vx204=holder.getVx204();


				    os.close();
				    
				    ArrayList<Double> predictions=new ArrayList<Double>();
				    Object[] noargs = new Object[0];
				    
				    //System.out.println( gp.execute_double(0, noargs));
				    System.out.println(gp.toStringNorm(0));
				    for(Stock s:stocks){
				    	vx1.set(StockProblem.movAvg(s,200-numDays,numDays));
		        		vx2.set(StockProblem.movAvg(s,200-numDays-50,numDays));
		        		vx3.set(StockProblem.movAvg(s,200-numDays-100,numDays));
		        		vx4.set(StockProblem.movAvg(s,200-numDays-150,numDays));
		        	
		        		
		        		/*
		        		
		        		vx5.set(s.getPrices().get(0));
		        		vx6.set(s.getPrices().get(1));
		        		
		        		vx7.set(s.getPrices().get(2));
		        		vx8.set(s.getPrices().get(3));
		        		vx9.set(s.getPrices().get(4));
		        		vx10.set(s.getPrices().get(5));
		        		vx11.set(s.getPrices().get(6));
		        		vx12.set(s.getPrices().get(7));
		        		vx13.set(s.getPrices().get(8));
		        		vx14.set(s.getPrices().get(9));
		        		vx15.set(s.getPrices().get(10));
		        		vx16.set(s.getPrices().get(11));
		        		vx17.set(s.getPrices().get(12));
		        		vx18.set(s.getPrices().get(13));
		        		vx19.set(s.getPrices().get(14));
		        		vx20.set(s.getPrices().get(15));
		        		vx21.set(s.getPrices().get(16));
		        		vx22.set(s.getPrices().get(17));
		        		vx23.set(s.getPrices().get(18));
		        		vx24.set(s.getPrices().get(19));
		        		vx25.set(s.getPrices().get(20));
		        		vx26.set(s.getPrices().get(21));
		        		vx27.set(s.getPrices().get(22));
		        		vx28.set(s.getPrices().get(23));
		        		vx29.set(s.getPrices().get(24));
		        		vx30.set(s.getPrices().get(25));
		        		vx31.set(s.getPrices().get(26));
		        		vx32.set(s.getPrices().get(27));
		        		vx33.set(s.getPrices().get(28));
		        		vx34.set(s.getPrices().get(29));
		        		vx35.set(s.getPrices().get(30));
		        		vx36.set(s.getPrices().get(31));
		        		vx37.set(s.getPrices().get(32));
		        		vx38.set(s.getPrices().get(33));
		        		vx39.set(s.getPrices().get(34));
		        		vx40.set(s.getPrices().get(35));
		        		vx41.set(s.getPrices().get(36));
		        		vx42.set(s.getPrices().get(37));
		        		vx43.set(s.getPrices().get(38));
		        		vx44.set(s.getPrices().get(39));
		        		vx45.set(s.getPrices().get(40));
		        		vx46.set(s.getPrices().get(41));
		        		vx47.set(s.getPrices().get(42));
		        		vx48.set(s.getPrices().get(43));
		        		vx49.set(s.getPrices().get(44));
		        		vx50.set(s.getPrices().get(45));
		        		vx51.set(s.getPrices().get(46));
		        		vx52.set(s.getPrices().get(47));
		        		vx53.set(s.getPrices().get(48));
		        		vx54.set(s.getPrices().get(49));
		        		vx55.set(s.getPrices().get(50));
		        		vx56.set(s.getPrices().get(51));
		        		vx57.set(s.getPrices().get(52));
		        		vx58.set(s.getPrices().get(53));
		        		vx59.set(s.getPrices().get(54));
		        		vx60.set(s.getPrices().get(55));
		        		vx61.set(s.getPrices().get(56));
		        		vx62.set(s.getPrices().get(57));
		        		vx63.set(s.getPrices().get(58));
		        		vx64.set(s.getPrices().get(59));
		        		vx65.set(s.getPrices().get(60));
		        		vx66.set(s.getPrices().get(61));
		        		vx67.set(s.getPrices().get(62));
		        		vx68.set(s.getPrices().get(63));
		        		vx69.set(s.getPrices().get(64));
		        		vx70.set(s.getPrices().get(65));
		        		vx71.set(s.getPrices().get(66));
		        		vx72.set(s.getPrices().get(67));
		        		vx73.set(s.getPrices().get(68));
		        		vx74.set(s.getPrices().get(69));
		        		vx75.set(s.getPrices().get(70));
		        		vx76.set(s.getPrices().get(71));
		        		vx77.set(s.getPrices().get(72));
		        		vx78.set(s.getPrices().get(73));
		        		vx79.set(s.getPrices().get(74));
		        		vx80.set(s.getPrices().get(75));
		        		vx81.set(s.getPrices().get(76));
		        		vx82.set(s.getPrices().get(77));
		        		vx83.set(s.getPrices().get(78));
		        		vx84.set(s.getPrices().get(79));
		        		vx85.set(s.getPrices().get(80));
		        		vx86.set(s.getPrices().get(81));
		        		vx87.set(s.getPrices().get(82));
		        		vx88.set(s.getPrices().get(83));
		        		vx89.set(s.getPrices().get(84));
		        		vx90.set(s.getPrices().get(85));
		        		vx91.set(s.getPrices().get(86));
		        		vx92.set(s.getPrices().get(87));
		        		vx93.set(s.getPrices().get(88));
		        		vx94.set(s.getPrices().get(89));
		        		vx95.set(s.getPrices().get(90));
		        		vx96.set(s.getPrices().get(91));
		        		vx97.set(s.getPrices().get(92));
		        		vx98.set(s.getPrices().get(93));
		        		vx99.set(s.getPrices().get(94));
		        		vx100.set(s.getPrices().get(95));
		        		vx101.set(s.getPrices().get(96));
		        		vx102.set(s.getPrices().get(97));
		        		vx103.set(s.getPrices().get(98));
		        		vx104.set(s.getPrices().get(99));
		        		vx105.set(s.getPrices().get(100));
		        		vx106.set(s.getPrices().get(101));
		        		vx107.set(s.getPrices().get(102));
		        		vx108.set(s.getPrices().get(103));
		        		vx109.set(s.getPrices().get(104));
		        		vx110.set(s.getPrices().get(105));
		        		vx111.set(s.getPrices().get(106));
		        		vx112.set(s.getPrices().get(107));
		        		vx113.set(s.getPrices().get(108));
		        		vx114.set(s.getPrices().get(109));
		        		vx115.set(s.getPrices().get(110));
		        		vx116.set(s.getPrices().get(111));
		        		vx117.set(s.getPrices().get(112));
		        		vx118.set(s.getPrices().get(113));
		        		vx119.set(s.getPrices().get(114));
		        		vx120.set(s.getPrices().get(115));
		        		vx121.set(s.getPrices().get(116));
		        		vx122.set(s.getPrices().get(117));
		        		vx123.set(s.getPrices().get(118));
		        		vx124.set(s.getPrices().get(119));
		        		vx125.set(s.getPrices().get(120));
		        		vx126.set(s.getPrices().get(121));
		        		vx127.set(s.getPrices().get(122));
		        		vx128.set(s.getPrices().get(123));
		        		vx129.set(s.getPrices().get(124));
		        		vx130.set(s.getPrices().get(125));
		        		vx131.set(s.getPrices().get(126));
		        		vx132.set(s.getPrices().get(127));
		        		vx133.set(s.getPrices().get(128));
		        		vx134.set(s.getPrices().get(129));
		        		vx135.set(s.getPrices().get(130));
		        		vx136.set(s.getPrices().get(131));
		        		vx137.set(s.getPrices().get(132));
		        		vx138.set(s.getPrices().get(133));
		        		vx139.set(s.getPrices().get(134));
		        		vx140.set(s.getPrices().get(135));
		        		vx141.set(s.getPrices().get(136));
		        		vx142.set(s.getPrices().get(137));
		        		vx143.set(s.getPrices().get(138));
		        		vx144.set(s.getPrices().get(139));
		        		vx145.set(s.getPrices().get(140));
		        		vx146.set(s.getPrices().get(141));
		        		vx147.set(s.getPrices().get(142));
		        		vx148.set(s.getPrices().get(143));
		        		vx149.set(s.getPrices().get(144));
		        		vx150.set(s.getPrices().get(145));
		        		vx151.set(s.getPrices().get(146));
		        		vx152.set(s.getPrices().get(147));
		        		vx153.set(s.getPrices().get(148));
		        		
		        		vx154.set(s.getPrices().get(149));
		        		vx155.set(s.getPrices().get(150));
		        		vx156.set(s.getPrices().get(151));
		        		vx157.set(s.getPrices().get(152));
		        		vx158.set(s.getPrices().get(153));
		        		vx159.set(s.getPrices().get(154));
		        		vx160.set(s.getPrices().get(155));
		        		vx161.set(s.getPrices().get(156));
		        		vx162.set(s.getPrices().get(157));
		        		vx163.set(s.getPrices().get(158));
		        		vx164.set(s.getPrices().get(159));
		        		vx165.set(s.getPrices().get(160));
		        		vx166.set(s.getPrices().get(161));
		        		vx167.set(s.getPrices().get(162));
		        		vx168.set(s.getPrices().get(163));
		        		vx169.set(s.getPrices().get(164));
		        		vx170.set(s.getPrices().get(165));
		        		vx171.set(s.getPrices().get(166));
		        		vx172.set(s.getPrices().get(167));
		        		vx173.set(s.getPrices().get(168));
		        		vx174.set(s.getPrices().get(169));
		        		vx175.set(s.getPrices().get(170));
		        		vx176.set(s.getPrices().get(171));
		        		vx177.set(s.getPrices().get(172));
		        		vx178.set(s.getPrices().get(173));
		        		vx179.set(s.getPrices().get(174));
		        		vx180.set(s.getPrices().get(175));
		        		vx181.set(s.getPrices().get(176));
		        		vx182.set(s.getPrices().get(177));
		        		vx183.set(s.getPrices().get(178));
		        		vx184.set(s.getPrices().get(179));
		        		vx185.set(s.getPrices().get(180));
		        		vx186.set(s.getPrices().get(181));
		        		vx187.set(s.getPrices().get(182));
		        		vx188.set(s.getPrices().get(183));
		        		vx189.set(s.getPrices().get(184));
		        		vx190.set(s.getPrices().get(185));
		        		vx191.set(s.getPrices().get(186));
		        		vx192.set(s.getPrices().get(187));
		        		vx193.set(s.getPrices().get(188));
		        		
		        		vx194.set(s.getPrices().get(189));
		        		vx195.set(s.getPrices().get(190));
		        		vx196.set(s.getPrices().get(191));
		        		vx197.set(s.getPrices().get(192));
		        		vx198.set(s.getPrices().get(193));
		        		vx199.set(s.getPrices().get(194));*/
		        		vx200.set(s.getPrices().get(195));
		        		vx201.set(s.getPrices().get(196));
		        		vx202.set(s.getPrices().get(197));
		        		vx203.set(s.getPrices().get(198));
		        		vx204.set(s.getPrices().get(199));

				    	System.out.println("x1 :"+vx1.getValue());
		        		predictions.add(gp.execute_double(0, noargs));
				    }
				   
				    FileWriter writer=new FileWriter(destFile);
				    BufferedWriter bw=new BufferedWriter(writer);
				   
				    double gain=0;
				    double all=0;
				    THRESH=calcAvg(predictions);
				    System.out.println(THRESH);
				    System.out.println(predictions.get(0));
				    for(int i=0;i<stocks.size();i++){
				    	if(predictions.get(i)>THRESH){
				    		
				    		bw.write(stocks.get(i).name);
				    		bw.newLine();
				    		gain+=predictions.get(i)-stocks.get(i).getPrices().get(199);
				    	}
				    	all+=predictions.get(i)-stocks.get(i).getPrices().get(199);
				    }
					System.out.println("gain is "+gain);
					System.out.println("indesx is "+all);
				    bw.close();
				}

			}
			catch (Exception e)
			{
				e.printStackTrace();
				System.out.println("problem");
			}
		}
		
	}
	
	private static double calcAvg(ArrayList<Double> predictions){

		double sum=0;
		System.out.println("funx");
		// for every Double in the population
		for(Double val:predictions)
		{
			System.out.println(val);
			// add this Double fitness
			sum+=val;
		}

		// return the average fitness
		return ((double)sum)/predictions.size();
	}
	private int getBestSolution(ArrayList<Double> population)
	{
		double max=-1;
		int max_index=-1;

		// for every Double in the population 
		for(int i=0;i<population.size();i++)
		{
			// the case that this Double's fitness is bigger then the current maximal
			if(population.get(i)>max)
			{
				// update the maxium fitness
				max=population.get(i);
				max_index=i;
			}

		}

		return max_index;
	}
}